import threading  # 多线程模块
from datetime import datetime  # 时间模块
import pygame  # 游戏模块，此处用于闹钟铃声
import tkinter as tk  # gui模块
from tkinter import messagebox  # gui模块中的消息框
from tkinter import filedialog  # gui模块中的文件对话框


class set_alarm_win(tk.Toplevel):
    def __init__(self, master):
        super().__init__(master)
        self.geometry("300x200+500+150")
        self.title("简易闹钟")

        self.str_alarm_time = tk.StringVar(self)
        self.sound_file = None

        label1 = tk.Label(self, text="请输入闹钟的时间(HH:MM:SS)：")
        label1.place(x=10, y=0)

        set_time = tk.Entry(self, textvariable=self.str_alarm_time, width=30)
        set_time.place(x=10, y=30)

        label2 = tk.Label(self, text="选择铃声：")
        label2.place(x=10, y=60)

        sound_btn = tk.Button(self, text="选择文件", command=self.select_sound_file)
        sound_btn.place(x=10, y=90)

        self.label3 = tk.Label(self, text=" ", width=30)
        self.label3.place(x=80, y=95)

        cancel_btn = tk.Button(self, text="取消", command=self.cancel_win)
        cancel_btn.place(x=10, y=140)

        ok_btn = tk.Button(self, text="确定", command=self.set_alarm)
        ok_btn.place(x=200, y=140)

    def select_sound_file(self):
        # 选择音频文件
        self.sound_file = filedialog.askopenfilename(filetypes=[("音频文件", "*.mp3")])
        if self.sound_file:
            self.label3.config(text=f"{self.sound_file.split('/')[-1]}")

    def cancel_win(self):
        # 摧毁窗口
        self.destroy()
        # 显示主窗口
        self.master.deiconify()

    def set_alarm(self):
        alarm_time = self.str_alarm_time.get()
        try:
            # 判断时间格式是否正确
            datetime.strptime(alarm_time, "%H:%M:%S")
        except ValueError:
            messagebox.showerror("错误", "输入的时间格式错误！")
            return
        if self.sound_file is None:
            # 判断是否选择音频
            messagebox.showerror("错误", "未选择音频铃声！")
            return

        # 传递闹钟信息
        self.master.set_alarm_info(alarm_time, self.sound_file)
        # 关闭设置窗口
        self.destroy()
        # 显示主窗口
        self.master.deiconify()


class ClockApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.geometry("250x200+500+150")  # 设置窗体页面大小
        self.title("简易闹钟")  # 设置标题

        self.alarm_bool = False  # 用来判断是否到闹钟设定的时间
        self.alarm_thread = None  # 用来计算闹钟时间的线程
        self.label = tk.Label(self, font=('Helvetica', 36))  # 显示当前时间
        self.label.place(x=30, y=20)

        self.del_btn = tk.Button(self, text="删除闹钟", command=self.delui)  # 删除闹钟按钮
        self.del_btn.place(x=30, y=120)

        self.set_btn = tk.Button(self, text="设置闹钟", command=self.setui)  # 设置闹钟按钮
        self.set_btn.place(x=150, y=120)

        self.alarm_info_label = tk.Label(self, text=" ")  # 显示闹钟定时时间label
        self.alarm_info_label.place(x=10, y=160)

        self.update_time()  # 刷新当前时间

    def delui(self):
        # 删除闹钟信息并中断闹钟
        if self.alarm_info_label:
            self.alarm_info_label.destroy()
        self.alarm_bool = False
        if self.alarm_thread:
            self.alarm_thread.join()

    def setui(self):
        # 隐藏主窗口
        self.withdraw()
        # 进入设置窗口
        set_alarm_win(self)

    def set_alarm_info(self, alarm_time, sound_file):
        self.alarm_time = alarm_time
        self.sound_file = sound_file
        # 删除旧的闹钟信息
        if self.alarm_info_label:
            self.alarm_info_label.destroy()
        # 创建新的闹钟信息
        self.alarm_info_label = tk.Label(self, text=f"闹钟时间:{alarm_time}")
        self.alarm_info_label.place(x=10, y=160)
        self.start_alarm_thread()

    def alarm_ontime(self):
        while self.alarm_bool:
            now = datetime.now()  # 获取当前时间
            if self.alarm_time == now.strftime("%H:%M:%S"):
                # 闹钟铃声
                self.sound_thread = threading.Thread(target=self.play_sound)
                self.sound_thread.start()  # 开启播放音乐线程
                if messagebox.askokcancel("闹钟", "闹钟响了，时间到！"):  # 窗口提示框
                    self.stop_sound()
                    if self.alarm_info_label:
                        self.alarm_info_label.destroy()
                self.alarm_bool = False
                break

    def play_sound(self):
        pygame.mixer.music.load(self.sound_file)  # 加载音乐
        pygame.mixer.music.play()  # 播放音乐

    def stop_sound(self):
        pygame.mixer.music.stop()  # 停止音乐

    def start_alarm_thread(self):  # 开启定时线程
        if self.alarm_thread:
            self.alarm_thread.join()
        self.alarm_bool = True
        self.alarm_thread = threading.Thread(target=self.alarm_ontime)
        self.alarm_thread.start()

    def update_time(self):
        current_time = datetime.now().strftime('%H:%M:%S')
        self.label.config(text=current_time)
        self.after(1000, self.update_time)  # 每1000毫秒（1秒）更新一次时间


if __name__ == "__main__":
    pygame.mixer.init()  # 初始化pygame
    app = ClockApp()  # 创建了一个闹钟对象
    app.mainloop()  # 循环监听事件
